#include "../include/Account.hh"
#include "../include/Utils.hh"
#include <iostream>
#include <iomanip>
#include <ctime>
#include <sstream>

// 静态方法：获取货币符号
std::string CurrencyConverter::getCurrencySymbol(Currency currency) {
    switch (currency) {
        case Currency::CNY: return "¥";
        case Currency::USD: return "$";
        case Currency::EUR: return "€";
        default: return "¥";
    }
}

// 静态方法：获取货币名称
std::string CurrencyConverter::getCurrencyName(Currency currency) {
    switch (currency) {
        case Currency::CNY: return "人民币";
        case Currency::USD: return "美元";
        case Currency::EUR: return "欧元";
        default: return "人民币";
    }
}

// 静态方法：获取汇率（基准币种为CNY）
double CurrencyConverter::getExchangeRate(Currency from, Currency to) {
    // 当前汇率（以CNY为基准）
    // 这些汇率应该从外部API获取或定期更新，这里使用固定值作为示例
    if (from == to) return 1.0;
    
    const double CNY_TO_USD = 0.1384; // 1元人民币 = 0.1384美元
    const double CNY_TO_EUR = 0.1271; // 1元人民币 = 0.1271欧元
    
    // 转换为CNY的汇率
    const double USD_TO_CNY = 1.0 / CNY_TO_USD; // 1美元 = 7.2254元人民币
    const double EUR_TO_CNY = 1.0 / CNY_TO_EUR; // 1欧元 = 7.8678元人民币
    
    // 计算from到to的汇率
    if (from == Currency::CNY) {
        if (to == Currency::USD) return CNY_TO_USD;
        if (to == Currency::EUR) return CNY_TO_EUR;
    } else if (from == Currency::USD) {
        if (to == Currency::CNY) return USD_TO_CNY;
        if (to == Currency::EUR) return USD_TO_CNY * CNY_TO_EUR;
    } else if (from == Currency::EUR) {
        if (to == Currency::CNY) return EUR_TO_CNY;
        if (to == Currency::USD) return EUR_TO_CNY * CNY_TO_USD;
    }
    
    return 1.0; // 默认返回1.0（相同货币）
}

// 静态方法：计算兑换后的金额（考虑1%手续费）
double CurrencyConverter::calculateExchangeAmount(double amount, Currency from, Currency to) {
    if (from == to) return amount;
    
    double exchangeRate = getExchangeRate(from, to);
    double fee = 0.01; // 1%手续费
    
    return amount * exchangeRate * (1.0 - fee);
}

Account::Account(std::string id, std::string owner, double initialBalance)
    : accountId(id), ownerName(owner), primaryCurrency(Currency::CNY) {
    
    // 初始化所有货币余额为0
    balances[Currency::CNY] = 0.0;
    balances[Currency::USD] = 0.0;
    balances[Currency::EUR] = 0.0;
    
    // 设置初始余额（人民币）
    if (initialBalance > 0.0) {
        balances[Currency::CNY] = initialBalance;
    }
}

std::string Account::getAccountId() const {
    return accountId;
}

std::string Account::getOwnerName() const {
    return ownerName;
}

double Account::getBalance(Currency currency) const {
    auto it = balances.find(currency);
    if (it != balances.end()) {
        return it->second;
    }
    return 0.0;
}

double Account::getBalance() const {
    return getBalance(primaryCurrency);
}

const std::map<Currency, double>& Account::getAllBalances() const {
    return balances;
}

void Account::setPrimaryCurrency(Currency currency) {
    primaryCurrency = currency;
}

Currency Account::getPrimaryCurrency() const {
    return primaryCurrency;
}

const std::vector<Transaction>& Account::getTransactionHistory() const {
    return transactionHistory;
}

void Account::addTransaction(const Transaction& transaction) {
    transactionHistory.push_back(transaction);
}

bool Account::deposit(double amount, const std::string& note) {
    return deposit(amount, Currency::CNY, note);
}

bool Account::deposit(double amount, Currency currency, const std::string& note) {
    if (!canDeposit()) {
        std::cout << "此类型账户不支持存款操作。" << std::endl;
        return false;
    }
    
    if (amount <= 0) {
        std::cout << "存款金额必须大于零。" << std::endl;
        return false;
    }
    
    // 增加对应货币的余额
    balances[currency] += amount;
    
    // 创建交易记录
    std::string currencySymbol = CurrencyConverter::getCurrencySymbol(currency);
    std::string currencyName = CurrencyConverter::getCurrencyName(currency);
    
    std::string transactionNote = note;
    if (note.empty()) {
        std::stringstream ss;
        ss << "存入" << currencyName << " " << currencySymbol << std::fixed << std::setprecision(2) << amount;
        transactionNote = ss.str();
    }
    
    // 生成交易ID
    std::stringstream transactionId;
    transactionId << "T" << std::time(nullptr) << "-" << rand() % 1000;
    
    // 创建交易记录并添加到历史
    Transaction transaction(transactionId.str(), TransactionType::DEPOSIT, amount, "", accountId, transactionNote);
    addTransaction(transaction);
    
    std::cout << "存款成功！当前" << currencyName << "余额: " 
              << currencySymbol << std::fixed << std::setprecision(2) << balances[currency] << std::endl;
    
    return true;
}

bool Account::withdraw(double amount, const std::string& note) {
    return withdraw(amount, Currency::CNY, note);
}

bool Account::withdraw(double amount, Currency currency, const std::string& note) {
    if (!canWithdraw()) {
        std::cout << "此类型账户不支持取款操作。" << std::endl;
        return false;
    }
    
    if (amount <= 0) {
        std::cout << "取款金额必须大于零。" << std::endl;
        return false;
    }
    
    if (balances[currency] < amount) {
        std::string currencySymbol = CurrencyConverter::getCurrencySymbol(currency);
        std::cout << "余额不足，当前" << CurrencyConverter::getCurrencyName(currency) 
                  << "余额: " << currencySymbol << std::fixed << std::setprecision(2) 
                  << balances[currency] << std::endl;
        return false;
    }
    
    // 减少对应货币的余额
    balances[currency] -= amount;
    
    // 创建交易记录
    std::string currencySymbol = CurrencyConverter::getCurrencySymbol(currency);
    std::string currencyName = CurrencyConverter::getCurrencyName(currency);
    
    std::string transactionNote = note;
    if (note.empty()) {
        std::stringstream ss;
        ss << "取出" << currencyName << " " << currencySymbol << std::fixed << std::setprecision(2) << amount;
        transactionNote = ss.str();
    }
    
    // 生成交易ID
    std::stringstream transactionId;
    transactionId << "T" << std::time(nullptr) << "-" << rand() % 1000;
    
    // 创建交易记录并添加到历史
    Transaction transaction(transactionId.str(), TransactionType::WITHDRAW, amount, accountId, "", transactionNote);
    addTransaction(transaction);
    
    std::cout << "取款成功！当前" << currencyName << "余额: " 
              << currencySymbol << std::fixed << std::setprecision(2) << balances[currency] << std::endl;
    
    return true;
}

bool Account::transfer(Account& destinationAccount, double amount, const std::string& note) {
    return transfer(destinationAccount, amount, Currency::CNY, note);
}

bool Account::transfer(Account& destinationAccount, double amount, Currency currency, const std::string& note) {
    if (!canTransferTo(destinationAccount)) {
        std::cout << "该类型账户不能转账到指定目标账户。" << std::endl;
        return false;
    }
    
    if (amount <= 0) {
        std::cout << "转账金额必须大于零。" << std::endl;
        return false;
    }
    
    if (balances[currency] < amount) {
        std::string currencySymbol = CurrencyConverter::getCurrencySymbol(currency);
        std::cout << "余额不足，当前" << CurrencyConverter::getCurrencyName(currency) 
                  << "余额: " << currencySymbol << std::fixed << std::setprecision(2) 
                  << balances[currency] << std::endl;
        return false;
    }
    
    // 减少源账户余额
    balances[currency] -= amount;
    
    // 增加目标账户余额
    destinationAccount.balances[currency] += amount;
    
    // 创建交易记录
    std::string currencySymbol = CurrencyConverter::getCurrencySymbol(currency);
    std::string currencyName = CurrencyConverter::getCurrencyName(currency);
    
    std::string transactionNote = note;
    if (note.empty()) {
        std::stringstream ss;
        ss << "转出" << currencyName << " " << currencySymbol << std::fixed << std::setprecision(2) << amount 
           << " 到账户 " << destinationAccount.getAccountId();
        transactionNote = ss.str();
    }
    
    // 生成交易ID
    std::stringstream transactionId;
    transactionId << "T" << std::time(nullptr) << "-" << rand() % 1000;
    
    // 创建交易记录并添加到历史
    Transaction transaction(transactionId.str(), TransactionType::TRANSFER, amount, 
                            accountId, destinationAccount.getAccountId(), transactionNote);
    addTransaction(transaction);
    destinationAccount.addTransaction(transaction);
    
    std::cout << "转账成功！";
    std::cout << "当前" << currencyName << "余额: " << currencySymbol 
              << std::fixed << std::setprecision(2) << balances[currency] << std::endl;
    
    return true;
}

bool Account::exchangeCurrency(Currency from, Currency to, double amount, const std::string& note) {
    if (amount <= 0) {
        std::cout << "兑换金额必须大于零。" << std::endl;
        return false;
    }
    
    if (balances[from] < amount) {
        std::string currencySymbol = CurrencyConverter::getCurrencySymbol(from);
        std::cout << "余额不足，当前" << CurrencyConverter::getCurrencyName(from) 
                  << "余额: " << currencySymbol << std::fixed << std::setprecision(2) 
                  << balances[from] << std::endl;
        return false;
    }
    
    // 获取兑换汇率和计算手续费后的金额
    double exchangeRate = CurrencyConverter::getExchangeRate(from, to);
    double fee = amount * 0.01; // 1%手续费
    double exchangedAmount = amount * exchangeRate * (1.0 - 0.01); // 扣除手续费后的金额
    
    // 更新余额
    balances[from] -= amount;
    balances[to] += exchangedAmount;
    
    // 准备交易记录
    std::string fromSymbol = CurrencyConverter::getCurrencySymbol(from);
    std::string toSymbol = CurrencyConverter::getCurrencySymbol(to);
    std::string fromName = CurrencyConverter::getCurrencyName(from);
    std::string toName = CurrencyConverter::getCurrencyName(to);
    
    std::string transactionNote = note;
    if (note.empty()) {
        std::stringstream ss;
        ss << "兑换 " << fromName << " " << fromSymbol << std::fixed << std::setprecision(2) << amount
           << " 为 " << toName << " " << toSymbol << std::fixed << std::setprecision(2) << exchangedAmount
           << "（手续费：" << fromSymbol << std::fixed << std::setprecision(2) << fee << "）";
        transactionNote = ss.str();
    }
    
    // 生成交易ID
    std::stringstream transactionId;
    transactionId << "T" << std::time(nullptr) << "-" << rand() % 1000;
    
    // 创建交易记录并添加到历史
    Transaction transaction(transactionId.str(), TransactionType::CURRENCY_EXCHANGE, amount, 
                            accountId, accountId, transactionNote);
    addTransaction(transaction);
    
    std::cout << "货币兑换成功！" << std::endl;
    std::cout << "兑换：" << fromName << " " << fromSymbol << std::fixed << std::setprecision(2) << amount;
    std::cout << " → " << toName << " " << toSymbol << std::fixed << std::setprecision(2) << exchangedAmount << std::endl;
    std::cout << "手续费：" << fromSymbol << std::fixed << std::setprecision(2) << fee << "（1%）" << std::endl;
    std::cout << "当前余额：" << std::endl;
    std::cout << "  " << fromName << ": " << fromSymbol << std::fixed << std::setprecision(2) << balances[from] << std::endl;
    std::cout << "  " << toName << ": " << toSymbol << std::fixed << std::setprecision(2) << balances[to] << std::endl;
    
    return true;
} 